#include "tools.h"

char ascii( char s ) {
    if ( s < 0x20 ) return '.';
    if ( s > 0x7E ) return '.';
    return s;
}

//using stderr just because qtcreator stows it correctly when mixed with qDebug(), qWarning(), etc
//otherwise it may not be shown in the correct spot in the output due to stdout/stderr caches
void hexdump( const void *d, int len ) {
    unsigned char *data;
    int i, off;
    data = (unsigned char*)d;
    fprintf( stderr, "\n");
    for ( off = 0; off < len; off += 16 ) {
        fprintf( stderr, "%08x  ", off );
        for ( i=0; i<16; i++ )
        {
            if( ( i + 1 ) % 4 )
            {
                if ( ( i + off ) >= len ) fprintf( stderr,"  ");
                else fprintf( stderr,"%02x",data[ off + i ]);
            }
            else
            {
                if ( ( i + off ) >= len ) fprintf( stderr,"   ");
                else fprintf( stderr,"%02x ",data[ off + i ]);
            }
        }

        fprintf( stderr, " " );
        for ( i = 0; i < 16; i++ )
            if ( ( i + off) >= len ) fprintf( stderr," ");
        else fprintf( stderr,"%c", ascii( data[ off + i ]));
        fprintf( stderr,"\n");
    }
    fflush( stderr );
}

void hexdump( const QByteArray &d, int from, int len )
{
    hexdump( d.data() + from, len == -1 ? d.size() : len );
}

QByteArray PaddedByteArray( const QByteArray &orig, quint32 padTo )
{
    //qDebug() << "need to pad from" << hex << orig.size() << "to nearest" << padTo;
    QByteArray padding( RU( orig.size(), padTo ) - orig.size(), '\0' );
    return orig + padding;
}

QByteArray ReadFile( const QString &path )
{
    QFile file( path );
    if( !file.exists() || !file.open( QIODevice::ReadOnly ) )
    {
        qWarning() << "ReadFile -> can't open" << path;
        return QByteArray();
    }
    QByteArray ret = file.readAll();
    file.close();
    return ret;
}

bool WriteFile( const QString &path, const QByteArray &ba )
{
    QFile file( path );
    if( !file.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
    {
        qWarning() << "WriteFile -> can't open" << path;
        return false;
    }
    if( file.write( ba ) != ba.size() )
    {
        file.close();
        qWarning() << "WriteFile -> can't write all the data to" << path;
        return false;
    }
    file.close();
    return true;
}
